<?php
/*
 * form.class.php
 *
 * Copyright 2011 Szontágh Ferenc <szontagh.ferenc@exahost.eu>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */
/**
 * Create HTML Forms, with PHP
 * @author    Ferenc Szontágh <szontagh.ferenc@exahost.eu>
 * @package htmlformgenerator
 * @TODO	translate to english :)
 */
class form
{
    /**
     * @var string    Az input mező megnevezése (name="$name")
     */
    var $name;
    /**
     * @var array    input mezőket tároló tömb
     */
    var $f = array();
    /**
     * @var array    a form tag attributumai
     */
    var $formAttrs = array();
    /**
     * @var bool    használjon-e label tag-et a form mező előtt
     */
    var $opt_label = true;
    /**
     * @var string    automatikus legyen-e az input mezők id-jnek kiosztása
     */
    var $opt_id = 'auto';

    function __construct($name)
    {
        $this->name = $name;
    }

    /**
     * @desc    Input mező hozzáadása a tömbhöz
     * @param string $type    input mező típusa: text,password,textarea,submit,reset,select...
     * @param string $name    input mező neve (name="$name")
     * @param string $show    a label tagben megjelenő felirat
     * @param mixed $value    input mező értéke, select esetén asszociatív tömb
     * @param mixed $id    input mező id értéke, ha a label be van kapcsolva, erre hivatkozik <label for=$id>
     * @param bool $label    rajzoljon-e label taget a form köré
     * @param mixed $pclass    a p tag: class="$pclass'
     * @return int    A hozzáadott input id-je
     */
    public function addInput($type, $name, $show, $value = '', $id = 0, $label = true, $pclass = null)
    {
        if ($this->opt_id == 'auto') {
            $id = count($this->f);
        }
        $this->f[$id] = array(
            'pclass' => $pclass,
            'show' => $show,
            'type' => $type,
            'name' => $name,
            'value' => $this->__typeConversion($value),
            'label' => $label,
            'attributes' => array()
        );
        return $id;
    }

    /**
     * @desc    típus konverzió
     * @param mixed $t    az érték, amelynek a típusát fixáljuk
     * @return
     */
    function __typeConversion($t)
    {
        if (is_numeric($t)) {
            return intval($t);
        }
        if (is_string($t)) {
            return $t;
        }
        if (is_bool($t)) {
            return (bool)$t;
        }
        return $t;
    }

    /**
     * @desc    attributum hozzáadása a mezőhöz
     * @param mixed $id    az input mező id-je, amelyet manipulálni szeretnénk
     * @param mixed $a    több attr hozzáadásakor asszociatív tömb, ellenkező esetben az attributum neve
     * @param mixed $b    hogyha a 2. paraméter nem tömb, abban az esetben az attr értékét adja
     * @return
     */
    public function addAttr($id, $a, $b = null)
    {
        if (is_array($a) AND $b == null) {
            $this->f[$id]['attributes'] = array_merge($this->f[$id]['attributes'], $a);
        } else {
            $this->f[$id]['attributes'][$a] = $b;
        }
    }

    /**
     * @desc    attributum törlése
     * @param mixed $id    az input mező id-je, amelyet manipulálni szeretnénk
     * @param string $n    az attributum neve
     * @param bool $setnull    false - törli az attributumot, true - null értéket ad az attributumnak és nem törli
     * @return
     */
    public function removeAttr($id, $n, $setnull = false)
    {
        if ($setnull === false) {
            unset($this->f[$id]['attributes'][$n]);
        } else {
            $this->f[$id]['attributes'][$n] = null;
        }
    }

    /**
     * @desc    attributum hozzáadása a form tag-hez
     * @param mixed $a    több attr hozzáadásakor asszociatív tömb, ellenkező esetben az attributum neve
     * @param mixed $b    hogyha a 2. paraméter nem tömb, abban az esetben az attr értékét adja
     * @return
     */
    public function addFormAttr($a, $b = null)
    {
        if (is_array($a) AND $b == null) {
            $this->formAttrs = array_merge($this->formAttrs, $a);
        } else {
            $this->formAttrs[$a] = $b;
        }
    }

    /**
     * @desc    form megjelenítése
     * @param mixed $id    az input mező id-je, amelyet megszeretnénk jeleníteni, null esetén a teljes form megjelenik
     * @return mixed
     */
    public function show($id = null)
    {
        $render = "<form method='post' name='" . $this->name . "'";
        foreach ($this->formAttrs as $fak => $fav) {
            $render .= ' ' . $fak . '="' . $fav . '" ';
        }
        $render .= "><fieldset>";
        if ($id != null) {
            return $this->render($id);
        } else {
            if ($this->opt_id == 'auto') {
                for ($z = 0; $z < count($this->f); $z++) {
                    $render .= $this->render($z);
                }
            } else {
                foreach ($this->f as $k => $v) {
                    //TODO: folyt köv...
                }
            }
        }
        $render .= "</fieldset></form>";
        return $render;
    }

    /**
     * @desc    gomb hozzáadása
     * @param string $name    a button neve
     * @param string $value    a button értéke
     * @param string $type    a button tipusa reset/submit
     * @param mixed $pclass    a hozzátartozó p tag css osztálya
     * @return mixed
     */
    public function addButton($name, $value, $type = 'submit', $pclass = null)
    {
        return $this->addInput($type, $name, null, $value, '', false, $pclass);
    }

    /**
     * @desc    egy form megjelenítése
     * @param mixed $id    az input mező id-je, amelyet megszeretnénk jeleníteni
     * @return mixed
     */
    private function render($id)
    {
        $form = "<p" . ($this->f[$id]['pclass'] == null ? '' : ' class="' . $this->f[$id]['pclass'] . '"') . ">";
        if ($this->opt_label === true AND $this->f[$id]['label'] === true) {
            $form .= '<label for="' . $id . '">' . $this->f[$id]['show'] . '</label>';
        }
        switch ($this->f[$id]['type']) {
            case 'email':
                $form .= '<input
						type="' . $this->f[$id]['type'] . '"
						name="' . $this->f[$id]['name'] . '"
						value="' . $this->f[$id]['value'] . '"
						id="' . $id . '"';
                foreach ($this->f[$id]['attributes'] as $k => $v) {
                    $form .= $k . '="' . $v . '"';
                }
                $form .= '/>';
                break;
            case 'submit':
            case 'reset':
            case 'password':
            case 'text':
                $form .= '<input
						type="' . $this->f[$id]['type'] . '"
						name="' . $this->f[$id]['name'] . '"
						value="' . $this->f[$id]['value'] . '"
						id="' . $id . '"';
                foreach ($this->f[$id]['attributes'] as $k => $v) {
                    $form .= $k . '="' . $v . '"';
                }
                $form .= '/>';
                break;
            case 'textarea':
                $form .= '<textarea
					name="' . $this->f[$id]['name'] . '"
					id="' . $id . '"';
                foreach ($this->f[$id]['attributes'] as $k => $v) {
                    $form .= $k . '="' . $v . '"';
                }
                $form .= '>' . $this->f[$id]['value'] . '</textarea>';
                break;
            case 'select':
                $form .= '<select
				name="' . $this->f[$id]['name'] . '"
				id="' . $id . '"';
                foreach ($this->f[$id]['attributes'] as $k => $v) {
                    if ($k != 'selected')
                        $form .= $k . '="' . $v . '"';
                }
                $form .= ">";
                $selected = false;
                if (isset($this->f[$id]['attributes']['selected'])) {
                    $selected = $this->f[$id]['attributes']['selected'];
                }
                unset($this->f[$id]['attributes']['selected']);
                $i = 0;
                foreach ($this->f[$id]['value'] as $k => $v) {
                    $default = '';
                    if ($i === $selected OR $selected == $k) {
                        $default = 'selected="selected"';
                    }
                    $form .= '<option value="' . $k . '" ' . $default . ' >' . $v . '</option>';
                    $i++;
                }
                $form .= '</select>';
                break;
        }
        if (isset($this->f[$id]['error'])) {
            $form .= '<span>';
            $form .= $this->f[$id]['error'];
            $form .= '</span>';
        }
        $form .= '</p>';
        return $form;
    }

    function __destroy()
    {
        unset($this->f);
    }
}